import { Router, RouteLocationNormalized } from 'vue-router'
import { ElMessage } from 'element-plus'

// 路由错误处理类
export class RouteErrorHandler {
  private router: Router
  private errorLog: Array<{
    timestamp: number
    error: string
    route: string
    fallbackUsed: string
    userAgent: string
  }> = []

  constructor(router: Router) {
    this.router = router
    this.setupErrorHandling()
  }

  // 设置错误处理
  private setupErrorHandling() {
    // 监听路由错误
    this.router.onError((error) => {
      console.error('路由错误:', error)
      this.logError(error.message, 'unknown', 'error-handler')
    })

    // 全局前置守卫中的错误处理
    this.router.beforeEach((to, from, next) => {
      try {
        // 验证路由是否存在
        if (to.matched.length === 0) {
          this.handleRouteNotFound(to, from, next)
          return
        }
        
        next()
      } catch (error) {
        console.error('路由守卫错误:', error)
        this.handleRouteError(to, from, next, error as Error)
      }
    })
  }

  // 处理路由未找到
  private handleRouteNotFound(
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: Function
  ) {
    const fallbackRoute = this.getFallbackRoute(to.path)
    
    this.logError(
      `路由未找到: ${to.path}`,
      to.path,
      fallbackRoute
    )

    // 显示用户友好的错误消息
    ElMessage.warning('页面不存在，正在为您跳转到合适的页面')

    // 执行回退
    next(fallbackRoute)
  }

  // 处理路由错误
  private handleRouteError(
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: Function,
    error: Error
  ) {
    const fallbackRoute = this.getFallbackRoute(to.path)
    
    this.logError(
      `路由错误: ${error.message}`,
      to.path,
      fallbackRoute
    )

    // 显示用户友好的错误消息
    ElMessage.error('页面加载失败，正在为您跳转到安全页面')

    // 执行回退
    next(fallbackRoute)
  }

  // 获取回退路由 - 多级回退系统
  private getFallbackRoute(originalPath: string): string {
    // 第一级：尝试同类型的默认页面
    if (originalPath.startsWith('/teacher')) {
      return '/teacher/dashboard'
    }

    if (originalPath.startsWith('/student')) {
      return '/student/dashboard'
    }

    if (originalPath.startsWith('/main')) {
      return '/main'
    }

    // 第二级：尝试开发首页
    if (originalPath !== '/') {
      return '/'
    }

    // 第三级：最后的回退 - 404页面
    return '/not-found'
  }

  // 记录错误日志
  private logError(error: string, route: string, fallback: string) {
    const logEntry = {
      timestamp: Date.now(),
      error,
      route,
      fallbackUsed: fallback,
      userAgent: navigator.userAgent
    }

    this.errorLog.push(logEntry)

    // 保持日志大小在合理范围内
    if (this.errorLog.length > 100) {
      this.errorLog.shift()
    }

    // 在开发环境中输出详细日志
    if (import.meta.env.DEV) {
      console.group('🚨 路由错误处理')
      console.error('错误:', error)
      console.info('原始路由:', route)
      console.info('回退路由:', fallback)
      console.info('时间:', new Date(logEntry.timestamp).toLocaleString())
      console.groupEnd()
    }

    // 可以在这里添加错误上报逻辑
    this.reportError(logEntry)
  }

  // 错误上报（可选）
  private reportError(logEntry: any) {
    // 在生产环境中，可以将错误发送到监控服务
    if (import.meta.env.PROD) {
      // 示例：发送到错误监控服务
      // fetch('/api/error-report', {
      //   method: 'POST',
      //   headers: { 'Content-Type': 'application/json' },
      //   body: JSON.stringify(logEntry)
      // }).catch(() => {
      //   // 静默处理上报失败
      // })
    }
  }

  // 获取错误日志（用于调试）
  public getErrorLog() {
    return [...this.errorLog]
  }

  // 清除错误日志
  public clearErrorLog() {
    this.errorLog = []
  }

  // 手动触发路由回退
  public fallbackToSafePage(currentPath?: string) {
    const path = currentPath || this.router.currentRoute.value.path
    const fallbackRoute = this.getFallbackRoute(path)
    
    this.logError(
      '手动触发路由回退',
      path,
      fallbackRoute
    )

    ElMessage.info('正在为您跳转到安全页面')
    this.router.push(fallbackRoute)
  }

  // 检查路由是否有效
  public async validateRoute(path: string): Promise<boolean> {
    try {
      const resolved = this.router.resolve(path)
      return resolved.matched.length > 0
    } catch {
      return false
    }
  }
}

// 创建路由错误处理实例的工厂函数
export function createRouteErrorHandler(router: Router): RouteErrorHandler {
  return new RouteErrorHandler(router)
}
